package cn.pconline.autoclub.service;

import cn.pconline.autoclub.config.SystemConfig;
import cn.pconline.autoclub.entity.Gift;
import cn.pconline.autoclub.entity.GiftConversion;
import cn.pconline.autoclub.entity.User;
import cn.pconline.autoclub.util.Pager;
import cn.pconline.r.client.EntityBuilder;
import cn.pconline.r.client.RClient;
import cn.pconline.r.client.ResponseExtractor;
import cn.pconline.r.client.SimpleHttpTemplate;

import com.alibaba.fastjson.JSONObject;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.http.HttpResponse;
import org.apache.http.ParseException;
import org.apache.http.StatusLine;
import org.apache.http.util.EntityUtils;
import org.gelivable.auth.entity.GeliSession;
import org.gelivable.auth.entity.GeliUser;
import org.gelivable.dao.GeliDao;
import org.gelivable.dao.GeliOrm;
import org.gelivable.dao.SqlBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;

/**
 *
 * @author ppc
 */
public class GiftService {

    @Autowired
    private GeliDao geliDao;
    @Autowired
    private GeliOrm geliOrm;
    @Autowired
    private PagerService pagerService;
    @Autowired
    private UserService userService;
    @Autowired
    private SystemConfig systemConfig;
    @Autowired
    private RClient rClient;
    @Autowired
    private SimpleHttpTemplate simpleHttpTemplate;
    private static final Logger log = LoggerFactory.getLogger(GiftService.class);

    public Gift find(long id) {
        try {
            return geliDao.find(Gift.class, id);
        } catch (DataAccessException ex) {
            return null;
        }
    }

    public GiftConversion findConversion(long id) {
        try {
            return geliDao.find(GiftConversion.class, id);
        } catch (DataAccessException ex) {
            return null;
        }
    }

    public int updateConversion(GiftConversion giftConversion) {
        giftConversion.setUpdateAt(new Date());
        GeliUser u = GeliSession.getCurrentUser();
        long uid = 0;
        if (u != null) {
            uid = u.getUserId();
        }
        giftConversion.setAuditBy(uid);
        return geliDao.update(giftConversion);
    }

    public int updateGift(Gift gift) {
        gift.setUpdateAt(new Date());
        GeliUser u = GeliSession.getCurrentUser();
        long uid = 0;
        if (u != null) {
            uid = u.getUserId();
        }
        gift.setUpdateBy(uid);
        return geliDao.update(gift);
    }

    /**
     * 根据状态查询礼品
     *
     * @param status
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<Gift> listGift(int status, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(Gift.class)).appendSql(" where  status=").appendValue(status);
        sql.appendSql(" order by seq asc,create_at desc");
        return pagerService.pager(Gift.class, sql, pageNo, pageSize);
    }

    /**
     * 查询上架和下架的礼品
     *
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<Gift> listGift(int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(Gift.class)).appendSql(" where  status !=").appendValue(Gift.STATUS_DELETE);
        sql.appendSql(" order by seq asc,create_at desc");
        return pagerService.pager(Gift.class, sql, pageNo, pageSize);
    }

    public Pager<GiftConversion> listConversion(long userId, long giftId, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(GiftConversion.class)).appendSql(" where 1=1");
        if (userId > 0) {
            sql.appendSql(" and user_id = ").appendValue(userId);
        }
        if (giftId > 0) {
            sql.appendSql(" and gift_id = ").appendValue(giftId);
        }
        sql.appendSql(" and status <> ").appendValue(GiftConversion.STATUS_UNPAYMENT);//不返回待付款的数据
        sql.appendSql(" order by create_at desc");//倒序
        return pagerService.pager(GiftConversion.class, sql, pageNo, pageSize);
    }

    public Pager<GiftConversion> listConversionWithGift(long userId, long giftId, String truename, int status, String beginDate, String endDate, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(GiftConversion.class)).appendSql(" where 1=1");
        if (userId > 0) {
            sql.appendSql(" and user_id = ").appendValue(userId);
        }
        if (giftId > 0) {
            sql.appendSql(" and gift_id = ").appendValue(giftId);
        }
        if (StringUtils.isNotBlank(truename)) {
            sql.appendSql(" and truename like ").appendValue("%" + truename + "%");
        }
        if (status > GiftConversion.STATUS_NOSELECT) {
            sql.appendSql(" and status=").appendValue(status);
        }
        if (StringUtils.isNotBlank(beginDate)) {
            sql.appendSql(" and create_at>=").appendValue(beginDate);
        }
        if (StringUtils.isNotBlank(endDate)) {
            sql.appendSql(" and create_at <=").appendValue(endDate);
        }
        sql.appendSql(" order by create_at desc");
        Pager<GiftConversion> pager = pagerService.pager(GiftConversion.class, sql, pageNo, pageSize);
        List<GiftConversion> list = pager.getResultList();
        if (list != null && list.size() > 0) {
            long[] gIds = new long[list.size()];
            for (int i = 0; i < list.size(); i++) {
            	GiftConversion giftConversion = list.get(i);
                gIds[i] = giftConversion.getGiftId();
                //设置用户对象
                User user = userService.findUser(giftConversion.getUserId());
                giftConversion.setUser(user);
            }
            List<Gift> gifts = geliDao.list(Gift.class, gIds);
            if (gifts != null) {
                for (int i = 0; i < gifts.size(); i++) {
                    list.get(i).setGift(gifts.get(i));
                }
            }
        }
        return pager;
    }

    public long createGift(Gift g) {
        GeliUser user = GeliSession.getCurrentUser();
        if (user != null) {
            g.setCreateBy(user.getUserId());
        }
        g.setCreateAt(new Date());
        return geliDao.create(g);
    }

    public GiftConversion createConversion(long userId, Gift gift, String trueName, String address, String postcode, String phone,int num) {
    	int curNum = gift.getCurNum();
        if (curNum < num) {
            return null;
        }
    	GiftConversion conversion = new GiftConversion();
        conversion.setGiftId(gift.getGiftId());
        conversion.setUserId(userId);
        conversion.setGold(gift.getGold()*num);
        conversion.setTrueName(trueName);
        conversion.setAddress(address);
        conversion.setPostcode(postcode);
        conversion.setPhone(phone);
        conversion.setNum(num);
        //创建时先把状态设为待付款,扣金币成功后再改为未发货
        conversion.setStatus(GiftConversion.STATUS_UNPAYMENT);
        
        Date cur = new Date();
        conversion.setCreateAt(cur);
        conversion.setUpdateAt(cur);
        long id = geliDao.create(conversion);
        if (id > 0) {
            updateGift(gift);
            return conversion;
        }
        return null;
    }

    /**
     * 该方法只给扣除金币成功后调用(修改订单状态为未发货,库存减num)
     *
     * @param giftConversion
     * @return
     */
    public int updateConversionToNormal(GiftConversion giftConversion, long logId, int num) {
        if (giftConversion == null) {
            return 0;
        }
        if (giftConversion.getStatus() == GiftConversion.STATUS_UNPAYMENT) {
            Gift gift = find(giftConversion.getGiftId());
            if (gift == null) {
                return 0;
            }
            giftConversion.setStatus(GiftConversion.STATUS_NOSEND);
            giftConversion.setLogId(logId);
            int count = updateConversion(giftConversion);
            if (count > 0) {
                if (gift.getCurNum() > 0) {
                    gift.setCurNum(gift.getCurNum() - num);
                    updateGift(gift);
                }
            }
            return count;
        }
        return 0;
    }

    /**
     * 根据common_session_id获取金币数，从任务系统获取
     *
     * @param uid
     * @return
     */
    public long getCoinsByUserId(String common_session_id, long uid) {
        String tastRoot = systemConfig.getTaskRoot();
        //   String comoonSession = cn.pconline.passport2.util.WebUtils.getCookie(request, systemConfig.getUserSessionName());
        long coins = 0L;
        String jsonString = "";
        String url = new StringBuilder(tastRoot).append("/intf/clubgc/getUserInfo.do?").append(systemConfig.getUserSessionName()).append("=").append(common_session_id).toString();
        try {
            jsonString = simpleHttpTemplate.get(url, null, 3000);
            JSONObject json = JSONObject.parseObject(jsonString);
            if (json != null) {
                return json.getLongValue("goldCount");//obj.getLong("gold");
            }
        } catch (Exception e) {
            log.error("Retrieve coins error:uid: {}, result: {}", uid, jsonString);
            log.error("Retrieve coins error", e);
        }
        return 0;
    }

    /**
     * 
     * @param commonSessionId
     * @param uid
     * @param gold 总消耗金币数
     * @param exchangeNum 兑换数量
     * @param exchangeGift 兑换物品名称
     * @return
     */
    public long updateUserGold(String commonSessionId, final long uid, long gold, int exchangeNum, String exchangeGift) {
        String taskRoot = systemConfig.getTaskRoot();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put(systemConfig.getUserSessionName(), commonSessionId);
        String encodeGiftName = exchangeGift;
        try {
            encodeGiftName = URLEncoder.encode(exchangeGift,"UTF-8");
        } catch (UnsupportedEncodingException ex) {
        }
        String url = taskRoot + "/intf/clubgc/exchangeReward.do?" + systemConfig.getUserSessionName() 
        		+ "=" + commonSessionId + "&amount=" + gold + "&exchangeNum=" + exchangeNum
        		+ "&exchangeGift=" + encodeGiftName;
        map.put("amount", gold);
        map.put("exchangeNum", exchangeNum);
        map.put("exchangeGift", exchangeGift);
        String result = simpleHttpTemplate.post(url, null, new ResponseExtractor<String>() {
            @Override
            public String extractData(HttpResponse response) throws IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() == 200) {
                    try {
                        return EntityUtils.toString(response.getEntity());
                    } catch (IOException ex) {
                        log.error("update user gold fail 1!", ex);
                    } catch (ParseException ex) {
                        log.error("update user gold fail 2!", ex);
                    }
                } else {
                    log.error("update user gold fail uid : " + uid + " statusCode is " + statusLine.getStatusCode());
                    try {
                        log.error(EntityUtils.toString(response.getEntity()));
                    } catch (IOException ex) {
                        log.error("update user gold fail--IOException", ex);
                    } catch (ParseException ex) {
                        log.error("update user gold fail--ParseException", ex);
                    }
                }
                return "";
            }
        }, null);
        if (result != null) {
            JSONObject obj = JSONObject.parseObject(result);
            if (obj != null) {
                if (obj.containsKey("status")) {
                    int status = obj.getIntValue("status");
                    if (status == Gift.STATUS_GOLD_OK) {
                        return obj.getLongValue("logId");
                    }
                }
            } else {
                return Gift.STATUS_GOLD_ERROR;
            }
        } else {
            return Gift.STATUS_GOLD_ERROR;
        }
        return Gift.STATUS_GOLD_FAIL;
    }

    /**
     * 系统返回金币
     *
     * @param logId
     * @param userId
     * @return
     */
    public int restorationGold(long logId, final long userId) {
        String taskRoot = systemConfig.getTaskRoot();
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("uid", userId);
        map.put("logId", logId);
        String result = simpleHttpTemplate.post(taskRoot + "/intf/clubgc/undoExchangeReward.do", null, new ResponseExtractor<String>() {
            @Override
            public String extractData(HttpResponse response) throws IOException {
                StatusLine statusLine = response.getStatusLine();
                if (statusLine.getStatusCode() == 200) {
                    try {
                        return EntityUtils.toString(response.getEntity());
                    } catch (IOException ex) {
                        log.error("update user gold fail 1!", ex);
                    } catch (ParseException ex) {
                        log.error("update user gold fail 2!", ex);
                    }
                } else {
                    log.error("update user gold fail uid : " + userId + " statusCode is " + statusLine.getStatusCode());
                    try {
                        log.error(EntityUtils.toString(response.getEntity()));
                    } catch (IOException ex) {
                        log.error("update user gold fail--IOException!", ex);
                    } catch (ParseException ex) {
                        log.error("update user gold fail--ParseException!", ex);
                    }
                }
                return "";
            }
        }, EntityBuilder.entity().params(map).build());
        if (result != null) {
            JSONObject obj = JSONObject.parseObject(result);
            if (obj != null) {
                int status = obj.getIntValue("status");
                return status;
            } else {
                return Gift.STATUS_GOLD_ERROR;
            }
        }
        return Gift.STATUS_GOLD_ERROR;
    }

    /**
     * 根据userId查询礼品兑换记录
     *
     * @param userId
     * @param pageNo
     * @param pageSize
     * @return
     */
    public Pager<GiftConversion> pagerLoadConversionByUserId(long userId, int pageNo, int pageSize) {
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select * from ").appendSql(geliOrm.getTableName(GiftConversion.class));
        sql.appendSql(" where user_id = ").appendValue(userId);
        sql.appendSql(" and (status = 1 or status = 0 or status = -1)");
        sql.appendSql(" order by create_at desc");
        return pagerService.pager(GiftConversion.class, sql, pageNo, pageSize);
    }

    /**
     * 根据userId查询礼品兑换记录数量
     *
     * @param userId
     * @return
     */
    public int countConversion(long userId) {
        if (userId <= 0) {
            return 0;
        }
        SqlBuilder sql = new SqlBuilder();
        sql.appendSql("select count(1) from ").appendSql(geliOrm.getTableName(GiftConversion.class));
        sql.appendSql(" where user_id =").appendValue(userId).appendSql(" and status !=").appendValue(GiftConversion.STATUS_UNPAYMENT);
        return geliDao.count(sql.getSql(), sql.getValues());
    }
}
